#include "common.h"

short PORT = 1234;
const char *IP = "127.0.0.1";
int sockfd ;

struct client{
    char name[20];//客户端连接上来时 输入的姓名
    int fd;//客户端的socket
};

struct sockaddr_in addr;
struct sockaddr_in addrnew;
struct client c[200] = {0};
int num = 0;

void down()
{
	printf("server is closing......\n");
	close(sockfd);
	exit(0);
}

void init()
{
	printf("server starts up.\n");
	sockfd = socket(PF_INET , SOCK_STREAM , 0);
	if(sockfd == -1)
		perror("socket") , exit(-1);
	addr.sin_family = PF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = inet_addr(IP);
	int reuseaddr = 1;
	setsockopt(sockfd , SOL_SOCKET, SO_REUSEADDR,&reuseaddr,sizeof(reuseaddr));
	int res = bind(sockfd , (struct sockaddr *)&addr , sizeof(addr));
	if(res == -1)
		perror("failed to bind.") , exit(-1);
	printf("bind......\n");
	listen(sockfd , 100);
	printf("listen......\n");
}

void sendtoAll(const char *mess)
{
	int i ;
	for(i = 0 ; i < num ; ++i)
	{
		if(c[i].fd != 0)
			send(c[i].fd , mess , strlen(mess) , 0);
	}
}

void* thread_recv(void *p)
{
	int fd = *(int *)p;
	char buf[200] = {};
	char name[20] = {};
	char mess[300] = {};
	//receive client name;
	recv(fd , name , sizeof(name) , 0);
	c[num].fd = fd;
	strcpy(c[num].name , name);
	printf("%s join \n",c[num].name);
	int cur_id = num;
	num++;
	sprintf(buf , "welcome %s here " , c[cur_id].name);
	sendtoAll(buf);
	while(1)
	{
		memset(buf , 0x00 , sizeof(buf));
		memset(mess , 0x00 , sizeof(mess));
		if(recv(fd , buf , sizeof(buf) , 0) <= 0)
		{
			printf("%s left .\n",c[cur_id].name);
			close(fd);
			return;
		}
		sprintf(mess , "%s say : %s" , c[cur_id].name , buf);
		printf("%s\n",mess);
		sendtoAll(mess);
	}	
}

void service()
{
	socklen_t len = sizeof(addr);
	while(1)
	{
		int newsock = accept(sockfd , (struct sockaddr *)&addr , &len);
		c[num].fd = newsock;
		pthread_t id ;
		pthread_create(&id , 0 , thread_recv , (void*)&newsock);		
	}
}

int main()
{
	signal(SIGINT , down);
	init();
	service();
	down();
}

